# !/usr/bin/evn python3
# -*- coding: utf-8 -*-
# File Name: api_page.py
# Created Date: 2017-12-05 13:03:07
from flask import current_app
from app.ext import db
from sqlalchemy import and_, or_, not_
from math import radians, cos, sin, asin, sqrt
import json
import requests
import geohash
from qiniu import Auth, put_file
import uuid

class Modelable():

    #生成分页对象的 json
    @staticmethod
    def res_page(temps):
        temp_page = dict(
                has_next=temps.has_next,
                has_prev=temps.has_prev,
                next_num=temps.next_num,
                total=temps.total,
                per_page=temps.per_page,
                pages=temps.pages
                )
        return temp_page


    
    #对象查询搜索
    @classmethod
    def model_search(cls, **kwargs):
        page = kwargs.get("page", 1)
        args = [getattr(cls, k) == v for k, v in kwargs.items() if v and hasattr(cls, k)]
        results = cls.query.filter(and_(*args)).paginate(int(page), per_page=10, error_out=False)
        t_page = Modelable.res_page(results)
        return results.items, t_page


    #根据两个经纬度来计算距离
    @staticmethod
    def haversine(lon1, lat1, lon2, lat2): # 经度1，纬度1，经度2，纬度2 （十进制度数）  
        # 将十进制度数转化为弧度  
        lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])  
        # haversine公式  
        dlon = lon2 - lon1   
        dlat = lat2 - lat1   
        a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2  
        c = 2 * asin(sqrt(a))   
        r = 6371 # 地球平均半径，单位为公里  
        return c * r  
    
    #搜索附近
    #定义距离是根据编码的多少来计算的
    #使用数据库模糊查询
    @classmethod
    def near_by(cls, lat=0, lon=0, radius=50):
        r =  3 if radius > 200 else 4
        location = geohash.encode(lat, lon, r)
        results = cls.query.filter(cls.geohash.like("{}%".format(location))).all()
        return results
    
    #解析地址经纬度
    def conver_to_lat_lon(self):
        url = "http://restapi.amap.com/v3/geocode/geo"
        headers = {"key": current_app.config['GAODE_KEY']}
        try:
            params = dict(address = self.province + self.city + self.district + self.street, city=self.city)
            res = requests.get(url, params=params, headers=headers)
            temp = json.loads(res.text)
            geocodes = temp.get("geocodes", None)
            if geocodes is None:
                return None
            temp_value = geocodes[0].get("location", None)
            if temp_value is None:
                return None
            lon, lat = temp_value.split(',')
            return geohash.encode(float(lat), float(lon))
        except Exception as e:
            print("失败{}".format(e))
            return None

    #解析经纬度到地址
    def latlon_to_addr(self, lat=None, lon=None):
        url = "http://restapi.amap.com/v3/geocode/regeo"
        headers = {"key": current_app.config['GAODE_KEY']}
        try:
            if lat is None and lon is None:
                lat, lon = geohash.decode(self.geohash)
            params = dict(location= ",".join([str(lon), str(lat)]))
            res = requests.get(url, params=params, headers=headers)
            temps = json.loads(res.text)
            region = temps.get("regeocode", None)
            if region is None:
                return None
            addr = region["formatted_address"]
            province = region["addressComponent"]["province"]
            city = region["addressComponent"]["city"]
            district = region["addressComponent"]["district"]
            street_name = region["addressComponent"]["township"]
            street = region["addressComponent"]["streetNumber"]["street"]
            street_number = region["addressComponent"]["streetNumber"]["number"]
            street = street if street else None
            province = province if province else None
            city = city if city else (province if province else None)
            district = district  if district else None
            return province, city, district, street
        except Exception as e:
            print("出现了错误 >>{}".format(e))
            return None

    #直接将经纬度转编码
    def conver_lbs(self, lat=0, lon=0):
        geohash.encode(lat, lon)


    def upload_image(self, f):
        q = Auth(access_key=current_app.config.get('QINIU_AK', None), secret_key=current_app.config.get('QINIU_SK', None))
        key = uuid.uuid4()
        bucket_name = current_app.config.get('BUCKET_NAME', None)
        base_url = current_app.config.get('QINIU_URL', None)
        token = q.upload_token(bucket_name, key, 3600)
        ret, info = put_file(token, key, f)
        if info.status_code == 200:
            return base_url + ret.get('key')
